package com.yigo.bsc.infra.repo;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yigo.bsc.api.dict.query.DictItemQuery;
import com.yigo.bsc.api.dict.resp.DictItemListResp;
import com.yigo.bsc.infra.repo.converter.DictDmo2PoConverter;
import com.yigo.bsc.infra.repo.dataobject.BscDictItemPO;
import com.yigo.bsc.infra.repo.dataobject.BscDictTypePO;
import com.yigo.bsc.infra.repo.mapper.DictItemMapper;
import com.yigo.bsc.infra.repo.mapper.DictTypeMapper;
import com.yigo.cuc.domain.dict.entity.DictItem;
import com.yigo.cuc.domain.dict.entity.DictType;
import com.yigo.cuc.domain.dict.repo.DictRepo;
import com.yigo.framework.http.BException;
import com.yigo.framework.http.RCodeEnum;
import lombok.NonNull;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.*;

/**
 * @author chenzl
 */
@Repository
public class DictRepoImpl implements DictRepo {
    @Resource
    private DictTypeMapper dictTypeMapper;
    @Resource
    private DictItemMapper dictItemMapper;

    /**
     * (dict_type_code = ? OR dict_type_name = ?)
     *
     * @param dictTypeCode
     * @param dictTypeName
     * @return
     */
    @Override
    public Long countDictTypeByCodeOrName(@NonNull String dictTypeCode, @NonNull String dictTypeName) {
        LambdaQueryWrapper<BscDictTypePO> wrapper = Wrappers.lambdaQuery();
        //(dict_type_code = ? OR dict_type_name = ?)
        wrapper.eq(BscDictTypePO::getDictTypeCode, dictTypeCode)
                .or().eq(BscDictTypePO::getDictTypeName, dictTypeName);
        return dictTypeMapper.selectCount(wrapper);
    }

    @Override
    public DictType save(DictType dmo) {
        BscDictTypePO po = DictDmo2PoConverter.INSTANCE.toPO(dmo);
        if (null == po.getId()) {
            if (dictTypeMapper.insert(po) == 0) {
                throw new BException(RCodeEnum.PERSIST_OBJECT_ERROR);
            }
            dmo.setId(po.getId());
        } else {
            if (dictTypeMapper.updateById(po) == 0) {
                throw new BException(RCodeEnum.PERSIST_OBJECT_ERROR);
            }
        }
        return dmo;
    }

    @Override
    public DictType findDictTypeById(@NonNull Serializable id) {
        BscDictTypePO po = dictTypeMapper.selectById(id);
        return DictDmo2PoConverter.INSTANCE.toDmo(po);
    }

    /**
     * (dict_type_code = ? AND (dict_item_code = ? OR dict_item_name = ?))
     *
     * @param dictTypeCode
     * @param dictItemCode
     * @param dictItemName
     * @return
     */
    @Override
    public Long countDictItemByTypeCodeAndCodeOrName(@NonNull String dictTypeCode, @NonNull String dictItemCode,
                                                     @NonNull String dictItemName) {
        LambdaQueryWrapper<BscDictItemPO> wrapper = Wrappers.lambdaQuery();
        //(dict_type_code = ? AND (dict_item_code = ? OR dict_item_name = ?))
        wrapper.eq(BscDictItemPO::getDictTypeCode, dictTypeCode)
                .and(w -> w.eq(BscDictItemPO::getDictItemCode, dictItemCode)
                        .or().eq(BscDictItemPO::getDictItemName, dictItemName));
        return dictItemMapper.selectCount(wrapper);
    }

    @Override
    public DictItem save(DictItem dmo) {
        BscDictItemPO po = DictDmo2PoConverter.INSTANCE.toPO(dmo);
        if (null == po.getId()) {
            if (dictItemMapper.insert(po) == 0) {
                throw new BException(RCodeEnum.PERSIST_OBJECT_ERROR);
            }
            dmo.setId(po.getId());
        } else {
            if (dictItemMapper.updateById(po) == 0) {
                throw new BException(RCodeEnum.PERSIST_OBJECT_ERROR);
            }
        }
        return dmo;
    }

    @Override
    public DictItem findDictItemById(@NonNull Serializable id) {
        BscDictItemPO po = dictItemMapper.selectById(id);
        return DictDmo2PoConverter.INSTANCE.toDmo(po);
    }

    @Override
    public List<DictItemListResp> queryDictItemList(@NonNull DictItemQuery query) {
        LambdaQueryWrapper<BscDictItemPO> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(StrUtil.isNotBlank(query.getId()), BscDictItemPO::getId, query.getId());
        wrapper.eq(StrUtil.isNotBlank(query.getDictTypeCode()), BscDictItemPO::getDictTypeCode, query.getDictTypeCode());
        wrapper.eq(StrUtil.isNotBlank(query.getDictItemCode()), BscDictItemPO::getDictItemCode, query.getDictItemCode());
        wrapper.eq(StrUtil.isNotBlank(query.getDictItemName()), BscDictItemPO::getDictItemName, query.getDictItemName());
        if (wrapper.isEmptyOfWhere()) {
            throw new BException(RCodeEnum.PARAMS_NULL_ERROR, "query");
        }
        wrapper.select(BscDictItemPO::getId, BscDictItemPO::getDictTypeCode, BscDictItemPO::getDictItemCode,
                BscDictItemPO::getDictItemName, BscDictItemPO::getOrderNum);
        wrapper.orderByAsc(BscDictItemPO::getOrderNum);
        List<BscDictItemPO> poList = dictItemMapper.selectList(wrapper);
        return DictDmo2PoConverter.INSTANCE.toItemListResp(poList);
    }
}
